package chenjiuxu.exoplayer;

import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;

import com.facebook.drawee.view.SimpleDraweeView;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.LoopingMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;

import java.util.ArrayList;

/**
 * Created by C.jiuxu on 2017/5/2.
 * 视频播放器   问题缓冲暂停没有反应
 */
public class CExoPlayerView extends FrameLayout {
    private final AspectRatioFrameLayout contentFrame;
    private final View shutterView;//快门
    private final SimpleDraweeView poster_img;//视频截图
    private ComponentListener componentListener;
    private final Context context;
    private SurfaceView surfaceView;//视频绘制界面
    private CPlayControlView controlView;//控制组件
    private SimpleExoPlayer player;
    private DefaultBandwidthMeter bandwidthMeter;
    private long position = 0;
    private boolean isPlay;//是否播放
    private boolean isEnd;//是否完成播放
    public ArrayList<String> videoList;
    private int windowIndex = 0;//当前播放第几个视频
    private Boolean show = true;//视频绘制界面切换标识
    private boolean isOne = true;//resume 第一次标识
    private boolean isNoWIFI = false;//是否在流量下播放  默认false
    public PlaySet playSet;//播放设置
    public boolean isUrl = true;//播放链接 默认是远程文件


    public CExoPlayerView(Context context) {
        this(context, null);
    }

    public CExoPlayerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CExoPlayerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        int resource = R.layout.c_exo_player_view;
        int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT;
        LayoutInflater.from(context).inflate(resource, this);//为页面加载布局
        componentListener = new ComponentListener();
        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);//焦点的能力 ChildView先处理
        contentFrame = (AspectRatioFrameLayout) findViewById(R.id.c_exo_player_view_arfl);//视频容器
        poster_img = (SimpleDraweeView) findViewById(R.id.c_exo_player_view_img);
        contentFrame.setAspectRatio(16 / 9f);
        if (contentFrame != null) setResizeModeRaw(contentFrame, resizeMode);//视频比例
        if (contentFrame != null) {
            ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            surfaceView = new SurfaceView(context);//添加surfaceView 绘制视频
            surfaceView.setLayoutParams(params);
            contentFrame.addView(surfaceView, 0);
        }
        shutterView = findViewById(R.id.c_exo_player_view_shutter);////快门
        View controllerPlaceholder = findViewById(R.id.c_exo_player_view_control);//控制组件替换
        if (controllerPlaceholder != null) {//替换组件
            controlView = new CPlayControlView(context, this, attrs);
            controlView.setLayoutParams(controllerPlaceholder.getLayoutParams());
            ViewGroup parent = ((ViewGroup) controllerPlaceholder.getParent());
            int controllerIndex = parent.indexOfChild(controllerPlaceholder);
            parent.removeView(controllerPlaceholder);
            parent.addView(controlView, controllerIndex);
        }
        videoList = new ArrayList<>();
    }

    /**
     * 初始化
     */
    public void prepare(PlaySet set) {
        if (set == null) set = new PlaySet();
        playSet = set;
        if (!TextUtils.isEmpty(this.playSet.img_url)) {
            if (poster_img.getVisibility() != VISIBLE) poster_img.setVisibility(VISIBLE);
            poster_img.setImageURI(this.playSet.img_url);
        }
        if (player != null) return;//防止二次初始化
        SimpleExoPlayer simpleExoPlayer = createPlayer();
        setPlayer(simpleExoPlayer);
        sleepPreventer();
    }
    // setVolume

    /**
     * 单个开始播放
     */
    public void startPlay(String url) {
        String videoUrl = null;
        if (videoList != null && videoList.size() == 1) {
            videoUrl = videoList.get(0);
        }
        if (TextUtils.equals(url, videoUrl)) {//相同 重新播放 或者提示
            controlView.anewPaly();
        } else {//播放链接不同时
            shutterView.setVisibility(VISIBLE);
            player.stop();
            position = 0;
            windowIndex = 0;
            videoList.clear();
            videoList.add(url);
            isUrl = isUrlNetwork(url) && isUrl;
            play(position);
        }
    }

    /**
     * 多个视频播放
     */
    public void startPlay(String[] urls) {
        shutterView.setVisibility(VISIBLE);
        player.stop();
        position = 0;
        windowIndex = 0;
        videoList.clear();
        for (String url : urls) {
            isUrl = isUrlNetwork(url) && isUrl;
            videoList.add(url);
        }
        play(position);
    }

    /**
     * 播放
     */
    private void play(long position) {
        if (isWIFi() && playSet.isAutoPlay) {//自动播放
            MediaSource mediaSource = packData();//封装数据
            player.prepare(mediaSource);//准备有源代码的玩家
            player.seekTo(windowIndex, position);
            player.setPlayWhenReady(true);
            isEnd = false;
        } else {
            playSet.isAutoPlay = true;//可以播放
            controlView.updateView(false);
        }
    }


    /**
     * 暂停或播放
     */
    public void playAnPause() {
        controlView.playAnPause();
    }

    /**
     * 重置数据状态
     */
    public void resetState() {
        position = 0;
        windowIndex = 0;
        videoList.clear();
    }

    /**
     * 设置视频监听切换视频 视频结束
     */
    public void setPlayListener(OnlayListener listener) {
        controlView.setPlayListener(listener);
    }

    /**
     * 切换屏幕
     */
    public void cutScreen() {
        controlView.screen();
    }

    /**
     * 隐藏全屏按键
     */
    public void hideZoomBt() {
        controlView.hideZoomBt();
    }

    /**
     * 播放上一条
     */
    public void pastPlay() {
        int index = getIndex();
        if (index > 0) player.seekTo(index - 1, 0);
    }

    /**
     * 播放下一条
     */
    public void nextPlay() {
        int index = getIndex();
        int p = index + 1;
        if (p < videoList.size()) player.seekTo(p, 0);
    }

    /**
     * 播放速度
     */
    public void setPlaySpeed(float speed) {
        PlaybackParameters playbackParameters = new PlaybackParameters(speed, speed);//变速播放
        player.setPlaybackParameters(playbackParameters);
    }

    /**
     * 改变绘制表面
     */
    public void changeShow(SurfaceView sv) {
        player.clearVideoSurface();
        if (show) {
            this.player.setVideoSurfaceView(sv);
        } else {
            this.player.setVideoSurfaceView(surfaceView);
        }
        show = !show;
    }

    /**
     * 重新开始播放
     */
    public void restartPlay() {
        play(position);
    }

    /**
     * 界面重新开始 activity生命周期
     */
    public void resume() {
        if (isOne) {
            isOne = false;
            return;
        }
        if (player != null) {
            if (!isPlay) return;
            if (isEnd) return;
            restartPlay();
        }
    }

    /**
     * 暂停 activity生命周期
     */
    public void pause() {
        if (player != null) {
            saveState();
            player.stop();//停止播放
            controlView.hideControlStrip();//进度条隐藏
        }
    }

    /**
     * 界面销毁 activity生命周期
     */
    public void destroy() {//释放资源
        if (player != null) {
            this.player.clearVideoListener(componentListener);
            componentListener = null;
            player.release();
            player = null;
            controlView.hideControlStrip();//进度条隐藏
        }
    }

    /**
     * 是否在播放
     */
    public boolean isPlay() {
        return player.getPlayWhenReady();
    }


    /**
     * 获取当前播放播放第几个
     */
    public int getIndex() {
        int index = player.getCurrentWindowIndex();
        if (playSet.isLooping) {//循环
            int size = videoList.size();
            if (size == 1) {
                return 0;
            } else {
                int a = (index + 1) % size;
                if (a == 0) {
                    return size - 1;
                } else {
                    return a - 1;
                }
            }
        } else {
            return index;
        }
    }


    /**
     * 视频比例模式
     */
    private void setResizeModeRaw(AspectRatioFrameLayout aspectRatioFrame, int resizeMode) {
        aspectRatioFrame.setResizeMode(resizeMode);
    }

    /**
     * 防止屏幕休眠
     */
    private void sleepPreventer() {
        if (context instanceof Activity) {
            Activity activity = (Activity) context;
            activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        }
    }


    /**
     * 视频数据包装
     */
    private MediaSource packData() {
        if (videoList.isEmpty()) throw new NullPointerException("视频uri为空");
        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context, Util.getUserAgent(context, "kandaola"), bandwidthMeter);//媒体数据加载产生的数据源实例。
        ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();//媒体数据生成解析器实例。
        MediaSource[] mediaSourceList = new MediaSource[videoList.size()];
        for (int i = 0; i < videoList.size(); i++)
            mediaSourceList[i] = new ExtractorMediaSource(Uri.parse(videoList.get(i)), dataSourceFactory, extractorsFactory, null, null);//这是MediaSource代表媒体播放。
        MediaSource mediaSource = new ConcatenatingMediaSource(mediaSourceList);//播放视频序列
        if (playSet.isLooping) mediaSource = new LoopingMediaSource(mediaSource);//循环播放
        return mediaSource;
    }


    /**
     * 创建player
     */
    private SimpleExoPlayer createPlayer() {
        bandwidthMeter = new DefaultBandwidthMeter();//网速监听
        TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);//网络状态监听
        TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);//自适应轨道选择
        SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(context, trackSelector);
        return player;
    }

    /**
     * 设置SimpleExoPlayer
     */
    private void setPlayer(SimpleExoPlayer player) {
        if (this.player != null) {
            this.player.clearVideoListener(componentListener);
            this.player.clearVideoSurfaceView(surfaceView);
        }
        this.player = player;
        controlView.setPlayer(player);
        if (shutterView != null) shutterView.setVisibility(VISIBLE);//显示遮盖
        if (player != null) {
            player.setVideoSurfaceView(surfaceView);
            player.setVideoListener(componentListener);
        }
    }

    /**
     * 保存播放器状态
     */
    private void saveState() {
        int state = player.getPlaybackState();
        windowIndex = player.getCurrentPeriodIndex();
        switch (state) {
            case ExoPlayer.STATE_READY://可以播放状态
                position = player.getCurrentPosition();//记录播放时间
                isPlay = player.getPlayWhenReady();
                break;
            case ExoPlayer.STATE_ENDED://播放完成
                position = 0;//记录播放时间
                windowIndex = 0;
                isEnd = true;
                break;
        }
    }

    /**
     * 判断播放资源是不是在云端
     */
    private boolean isUrlNetwork(String url) {
        String s = url.substring(0, 4);
        if (TextUtils.equals("http", s)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断wifi是否链接
     */
    private Boolean isWIFi() {
        if (isNoWIFI) return true;
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
        if (activeNetInfo != null && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI) {
            return true;
        } else {
            if (isUrl) {//不是本地文件
                Toast.makeText(context, "你正在使用手机流量", Toast.LENGTH_LONG).show();
                isNoWIFI = true;
                return false;
            } else {
                return true;
            }
        }
    }

    /**
     * 状态监听器
     */
    private class ComponentListener implements SimpleExoPlayer.VideoListener {
        @Override
        public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {//视频的大小发生变化
            if (contentFrame != null) {
                float aspectRatio = height == 0 ? 1 : (width * pixelWidthHeightRatio) / height;
                contentFrame.setAspectRatio(aspectRatio);
            }
        }

        @Override
        public void onRenderedFirstFrame() {//开始绘制时
            if (shutterView != null) {
                shutterView.setVisibility(INVISIBLE);
                if (poster_img.getVisibility() != INVISIBLE) poster_img.setVisibility(INVISIBLE);
            }
            isEnd = false;
        }
    }

    /**
     * 播放监听
     */
    public interface OnlayListener {
        void currentPlay(int windowIndex);//当前播放
        void endPlay();//播放完成
    }

    /**
     * 播放设置类
     */
    public class PlaySet {
        public boolean isAutoPlay = true;//是否自动播放 默认自动播放
        public Boolean isLooping = false;//是否循环播放 默认不循环
        public String img_url;//视频封面
    }

    public PlaySet getPlaySet() {
        return new PlaySet();
    }
}
